package com.gitee.wsl.text.regex.sample

private const val IP_V4_SEGMENT_FORMAT = "(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])"
private const val IPV4_ADDRESS_FORMAT = "($IP_V4_SEGMENT_FORMAT[.]){3}$IP_V4_SEGMENT_FORMAT"
val Regex.Companion.ipV4AddressRegExp get() = Regex("^$IPV4_ADDRESS_FORMAT$")

fun String.isIpV4Address() = Regex.ipV4AddressRegExp.matches(this)

private const val IPV6_SEGMENT_FORMAT = "(?:[0-9a-fA-F]{1,4})"

@Suppress("RegExpUnnecessaryNonCapturingGroup")
val Regex.Companion.ipV6AddressRegExp get() = Regex(
    "^(" +
            "(?:$IPV6_SEGMENT_FORMAT:){7}(?:$IPV6_SEGMENT_FORMAT|:)|" +
            "(?:$IPV6_SEGMENT_FORMAT:){6}(?:$IPV4_ADDRESS_FORMAT|:$IPV6_SEGMENT_FORMAT|:)|" +
            "(?:$IPV6_SEGMENT_FORMAT:){5}(?::$IPV4_ADDRESS_FORMAT|(:$IPV6_SEGMENT_FORMAT){1,2}|:)|" +
            "(?:$IPV6_SEGMENT_FORMAT:){4}(?:(:$IPV6_SEGMENT_FORMAT){0,1}:$IPV4_ADDRESS_FORMAT|(:$IPV6_SEGMENT_FORMAT){1,3}|:)|" +
            "(?:$IPV6_SEGMENT_FORMAT:){3}(?:(:$IPV6_SEGMENT_FORMAT){0,2}:$IPV4_ADDRESS_FORMAT|(:$IPV6_SEGMENT_FORMAT){1,4}|:)|" +
            "(?:$IPV6_SEGMENT_FORMAT:){2}(?:(:$IPV6_SEGMENT_FORMAT){0,3}:$IPV4_ADDRESS_FORMAT|(:$IPV6_SEGMENT_FORMAT){1,5}|:)|" +
            "(?:$IPV6_SEGMENT_FORMAT:){1}(?:(:$IPV6_SEGMENT_FORMAT){0,4}:$IPV4_ADDRESS_FORMAT|(:$IPV6_SEGMENT_FORMAT){1,6}|:)|" +
            "(?::((?::$IPV6_SEGMENT_FORMAT){0,5}:$IPV4_ADDRESS_FORMAT|(?::$IPV6_SEGMENT_FORMAT){1,7}|:))" +
            ")(%[0-9a-zA-Z-.:]+)?$"
)

fun String.isIpV6Address() = Regex.ipV6AddressRegExp.matches(this)

fun String.isIpAddress() = isIpV4Address() || isIpV6Address()

fun String.isIP(): Boolean =
    Regex.IP_ADDRESS.matches(this)

internal const val IP_ADDRESS_STR =
    "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9]))"

val Regex.Companion.IP_ADDRESS
    get() = IP_ADDRESS_STR.toRegex()

fun String.isValidMACAddress(): Boolean =
    Regex.PATTERN_MAC.matches(this)

val Regex.Companion.PATTERN_MAC: Regex
    get() = "^([0-9A-Fa-f]{2}[\\.:-]){5}([0-9A-Fa-f]{2})$".toRegex()

//var MAC_ADDRESS = "((?:[a-fA-F0-9]{1,2}[:-]){5}[a-fA-F0-9]{1,2})|((?:[a-fA-F0-9]{1,4}[.]){2}[a-fA-F0-9]{1,4})|[a-fA-F0-9]{12}|0x(\\d{12}).+ETHER"
